package com.vadmin.vadminjava.common;
import com.alibaba.fastjson.JSONObject;
import com.vadmin.vadminjava.db.DBUtil;

import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.net.URLEncoder;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;

import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;



/**
 * 通用工具包
 */
public class CommonUtils {

    public static JSONObject mapToJSONObject(Map<String, Object> map) {
        JSONObject resultJson = new JSONObject();
        Iterator it = map.keySet().iterator();
        while (it.hasNext()) {
            String key = (String) it.next();
            resultJson.put(key, map.get(key));
        }
        return resultJson;
    }


    /**
     * 时间格式-带毫秒
     *
     * @description:
     * @param:
     * @return:
     * @author
     * @date: 2021/1/2 14:56
     */
    public static String millisecondTimeFormat = "yyyy-MM-dd HH:mm:ss:SSS";
    public static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    // 匹配数字、英文字母、汉字的正则表达式
    public static String regularExpression01 = "[^0-9a-zA-Z\\u4e00-\\u9fa5]";

    /**
     * 普通时间格式
     *
     * @description:
     * @param:
     * @return:
     * @author
     * @date: 2021/1/2 14:56
     */
    public static String ordinaryTimeFormat = "yyyy-MM-dd HH:mm:ss";

    /**
     * 根据毫秒数获取当前时间
     *
     * @param time
     * @return
     */
    public static String getDateWithMills(Long time) {
        String result = null;
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
        result = simpleDateFormat.format(new Date(time));
        return result;
    }

    public static String getDateWithMills(Long time, String timeFormat) {
        String result = null;
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(timeFormat);
        result = simpleDateFormat.format(new Date(time));
        return result;
    }

    /**
     * 获取系统当前时间 format:yyyy-MM-dd HH:mm:ss:SSS
     *
     * @return 固定格式的当前系统时间
     */
    public static String getSystemCurrentTime() {

        return getTimeWithMills(System.currentTimeMillis());

    }

    /**
     * 根据时间戳获取格式化后的时间 format:yyyy-MM-dd HH:mm:ss:SSS
     *
     * @param mills 时间毫秒数
     * @return 固定格式的指定时间
     */
    public static String getTimeWithMills(Long mills) {
        String result = null;

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");

        result = simpleDateFormat.format(new Date(mills));

        return result;

    }

    /**
     * 将utc时间转换成cst(北京时间)时间
     *
     * @param UTCStr
     * @param format
     * @return
     */
    public static Long UTCToCST(String UTCStr, String format) {
        Date date = null;
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        try {
            UTCStr = UTCStr.replaceAll("T", " ").replaceAll("Z", "");
            date = sdf.parse(UTCStr);
        } catch (ParseException ex) {
            Logger.getLogger(CommonUtils.class.getName()).log(Level.SEVERE, null, ex);
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR, calendar.get(Calendar.HOUR) + 8);
        return calendar.getTimeInMillis();
    }

    /**
     * 重新格式化时间
     *
     * @param date
     * @param orignalFormat
     * @param targetFormat
     * @return
     */
    public static String formartDate(String date, String orignalFormat, String targetFormat) {
        String result = date;
        SimpleDateFormat orignalDateFormat = new SimpleDateFormat(orignalFormat);
        SimpleDateFormat targetDateFormat = new SimpleDateFormat(targetFormat);
        try {
            result = targetDateFormat.format(new Date(orignalDateFormat.parse(date).getTime()));
        } catch (ParseException ex) {
            Logger.getLogger(CommonUtils.class.getName()).log(Level.SEVERE, null, ex);
        }
        return result;
    }

    /**
     * 使用标准URL Encode编码。注意和JDK默认的不同，空格被编码为%20而不是+。
     *
     * @param s String字符串
     * @return URL编码后的字符串
     */
    public static String urlEncode(String s) {
        try {
            return URLEncoder.encode(s, "UTF-8").replaceAll("\\+", "%20");
        } catch (UnsupportedEncodingException e) {
            throw new IllegalArgumentException("UTF-8 encoding not supported!");
        }
    }

    public static String toQueryString(Map<String, String> params) {
        return String.join("&", params.entrySet().stream().map((entry) -> {
            return entry.getKey() + "=" + urlEncode(entry.getValue());
        }).collect(Collectors.toList()));
    }

    public static String UnixTimestamp() {
        Long timestamp = System.currentTimeMillis();
        Long mills = timestamp % 1000;
        return (timestamp - mills) / 1000 + "." + mills;

    }

    /**
     * 将返回的iso8601(utc-0)格式时间转换为gmt(utc-8)格式时间毫秒数
     *
     * @param iosDate
     * @return
     */
    public static Long IOS2Long(String iosDate) {

        Long timeMills = 1587011697236L;
        try {
            String pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
            DateFormat format = new SimpleDateFormat(pattern);
            Date date = format.parse(iosDate);
            format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
            timeMills = format.parse(format.format(date)).getTime() + 3600000 * 8L;
        } catch (ParseException ex) {
            Logger.getLogger(CommonUtils.class.getName()).log(Level.SEVERE, null, ex);
        }
        return timeMills;

    }


    /**
     * 获取指定时间的毫秒数
     *
     * @param date
     * @param format
     * @return
     */
    public static Long getDateMills(String date, String format) {
        Long result = 0l;
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);

        try {
            result = simpleDateFormat.parse(date).getTime();
        } catch (ParseException ex) {
            Logger.getLogger(CommonUtils.class.getName()).log(Level.SEVERE, null, ex);
        }
        return result;
    }

    /**
     * 详情结果不能一概而论，预防错误，避免引起不必要麻烦
     *
     * @description:
     * @param:
     * @return:
     * @author
     * @date: 2020/12/6 15:34
     */
    public static String getValueStrNoError(JSONObject source, String information) {
        if (source == null || source.isEmpty()) return "";
        if (!source.containsKey(information)) return "";
        String result = source.getString(information);
        if (StringUtils.isEmpty(result)) return "";
        return result;
    }

    public static int convertInt(String variable, int defaults) {
        try {
            return Integer.parseInt(variable);
        } catch (Exception ex) {
            return defaults;
        }
    }

    public static Integer CINTN(String variable, Integer defaultS) {
        try {
            return Integer.parseInt(variable);
        } catch (Exception ex) {
            return defaultS;
        }
    }

    /**
     * 跨域设置
     *
     * @description:
     * @param:
     * @return:
     * @author
     * @date: 2020/12/8 9:30
     */
    public static boolean crossDomainAllowed(HttpServletRequest request, HttpServletResponse response) {
        /* 允许跨域的主机地址 */
        response.setHeader("Access-Control-Allow-Origin", "*");
        /* 允许跨域的请求方法GET, POST, HEAD 等 */
        response.setHeader("Access-Control-Allow-Methods", "*");
        /* 重新预检验跨域的缓存时间 (s) */
        response.setHeader("Access-Control-Max-Age", "3600");
        /* 允许跨域的请求头 */
        response.setHeader("Access-Control-Allow-Headers", "*");
        /* 是否携带cookie */
        response.setHeader("Access-Control-Allow-Credentials", "true");

        if ("OPTIONS".equals(request.getMethod())) {
            return false;
        }
        return true;
    }

    /**
     * @description: 计算两个时间差
     * @param:
     * @return:
     * @author
     * @date: 2020/12/24 15:09
     */
    public static JSONObject getDatePoor(Date endDate, Date nowDate) {
        JSONObject text = new JSONObject();
        long nd = 1000 * 24 * 60 * 60;
        long nh = 1000 * 60 * 60;
        long nm = 1000 * 60;
        long ns = 1000;
        // 获得两个时间的毫秒时间差异
        long diff = endDate.getTime() - nowDate.getTime();
        // 计算差多少天
        long day = diff / nd;
        // 计算差多少小时
        long hour = diff % nd / nh;
        // 计算差多少分钟
        long min = diff % nd % nh / nm;
        // 计算差多少秒//输出结果
        long sec = diff % nd % nh % nm / ns;
        text.put("day", day);
        text.put("hour", hour);
        text.put("min", min);
        text.put("sec", sec);
        text.put("character", day + "天," + hour + "时," + min + "分");

        maximumTime(text);
        return text;
    }

    /**
     * @description: 寻找最大 最有效时间
     * @param:
     * @return:
     * @author
     * @date: 2020/12/25 14:38
     */
    public static void maximumTime(JSONObject time) {
        Long day = time.getLong("day");
        Long hour = time.getLong("hour");
        Long min = time.getLong("min");
        Long sec = time.getLong("sec");

        String text = "";
        try {
            if (day != null && day > 0) {
                text = day + "天之前";
                return;
            }
            if (hour != null && hour > 0) {
                text = hour + "小时之前";
                return;
            }
            if (min != null && min > 0) {
                text = min + "分之前";
                return;
            }
            if (sec != null && sec > 0) {
                text = sec + "秒之前";
                return;
            }
        } finally {
            time.put("text", text);
        }
    }

    /**
     * @description: 指定的时间，转换为utc的24小时制
     * @param:
     * @return:
     * @author
     * @date: 2020/12/25 14:27
     */
    public static JSONObject calculatingTime(String date) {
        JSONObject map = new JSONObject();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date(CommonUtils.getDateMills(date, millisecondTimeFormat)));

        Calendar utc = Calendar.getInstance();
        utc.setTime(calendar.getTime());
        utc.set(Calendar.HOUR_OF_DAY, utc.get(Calendar.HOUR_OF_DAY) - 24);      // 时间和UTC转换

        Calendar thatDay = Calendar.getInstance();
        thatDay.setTime(utc.getTime());
        thatDay.add(Calendar.HOUR_OF_DAY, 24);      // utc结束时间

        map.put("utc_start", utc.getTimeInMillis());
        map.put("utc_end", thatDay.getTimeInMillis());
        map.put("utc_start1", utc.getTime().toLocaleString());
        map.put("utc_end1", thatDay.getTime().toLocaleString());

        return map;
    }

    /**
     * 本地时间转化为UTC时间
     *
     * @param
     * @return
     * @author wgs
     * @date 2018年10月19日 下午2:23:43
     */
    public static Date localToUTC(long localTimeInMillis) {
        /** long时间转换成Calendar */
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(localTimeInMillis);
        /** 取得时间偏移量 */
        int zoneOffset = calendar.get(Calendar.ZONE_OFFSET);
        /** 取得夏令时差 */
        int dstOffset = calendar.get(Calendar.DST_OFFSET);
        /** 从本地时间里扣除这些差量，即可以取得UTC时间*/
        calendar.add(Calendar.MILLISECOND, -(zoneOffset + dstOffset));
        /** 取得的时间就是UTC标准时间 */
        Date utcDate = new Date(calendar.getTimeInMillis());
        return utcDate;
    }

    /**
     * @description: 返回时间格式如：2020-02-17 00:00:00
     * @param:
     * @return:
     * @author
     * @date: 2020/12/26 12:41
     */
    public static String getStartOfDay(Date time) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(calendar.getTime());
    }

    /**
     * @description: 返回时间格式如：2020-02-19 23:59:59
     * @param:
     * @return:
     * @author
     * @date: 2020/12/26 12:41
     */
    public static String getEndOfDay(Date time) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(calendar.getTime());
    }

    /**
     * 功能描述: form-data转json
     *
     * @param:
     * @return:
     * @auther: llm
     * @detail:
     * @date: 2020-03-26 16:52
     */
    public static JSONObject formDataMap(HttpServletRequest request) {
        Map<String, String[]> params = request.getParameterMap();
        JSONObject map = new JSONObject();
        params.keySet().forEach(i -> {
            map.put(i, params.get(i)[0]);
        });
        return map;
    }

    /**
     * json转url
     *
     * @param map
     * @return
     */
    public static String gerprestr(JSONObject map) {
        StringBuffer sb = new StringBuffer("");
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
        }
        String str = sb.toString();
        return str.substring(0, str.length() - 1);
    }

    //获取当前月时间
    public static String[] getTheCurrentMonthTime() {
        String[] arr = new String[2];
        int month = new Date().getMonth();

        //获取当前月第一天：
        Calendar c = Calendar.getInstance();
        c.set(Calendar.MONTH, month);
        c.add(Calendar.MONTH, 0);
        c.set(Calendar.DAY_OF_MONTH, 1);

        //获取当前月最后一天
        Calendar ca = Calendar.getInstance();
        ca.set(Calendar.MONTH, month);
        ca.add(Calendar.MONTH, 0);
        ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH));
        arr[0] = simpleDateFormat.format(c.getTime());
        arr[1] = simpleDateFormat.format(ca.getTime());
        return arr;
    }

    /**
     * 这个是干嘛的？
     * @param days
     * @return
     */
    public static String getTimesMillisIncrease(Integer days){
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar c = Calendar.getInstance();
        //System.out.println("当前日期:"+sf.format(c.getTime()));
        c.add(Calendar.DAY_OF_MONTH, days); //增加天数
        String _ret = String.valueOf(c.getTimeInMillis());
        //System.out.println("增加一天后日期:"+sf.format(c.getTime()));
        //System.out.println("转成timestamp:"+ _ret);
        return _ret;
    }


    /**
     * 消除符号
     *
     * @description:
     * @param:
     * @return:
     * @author
     * @date: 2021/7/17 15:21
     */
    public static String deleteSymbol(String info) {
        return info.replace("[\"", "").replace("\"]", "").replace("[", "").replace("]", "");
    }



    //读取body流
    public static String readBodyInfo(HttpServletRequest request) {
        try {
            BufferedReader reader = request.getReader();
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
            return sb.toString();
        } catch (Exception e) {

        }
        return null;
    }



    //字符串数组，转换数组
    public static Object stringToArray(String val) {
        return CommonUtils.deleteSymbol(val).split(",");
    }

    /**
     * 切分list
     *
     * @param sourceList
     * @param groupSize  每组定长
     * @return
     */
    public static List<List> splitList(List sourceList, int groupSize) {
        int length = sourceList.size();
        // 计算可以分成多少组
        int num = (length + groupSize - 1) / groupSize;
        List<List> newList = new ArrayList<>(num);
        for (int i = 0; i < num; i++) {
            // 开始位置
            int fromIndex = i * groupSize;
            // 结束位置
            int toIndex = (i + 1) * groupSize < length ? (i + 1) * groupSize : length;
            newList.add(sourceList.subList(fromIndex, toIndex));
        }
        return newList;
    }




}
